package com.zb.zeus.common.redis.utils;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class RedisSequenceUtil {

    private static RedisTemplate redisTemplate;

    public static void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisSequenceUtil.redisTemplate = redisTemplate;
    }

    /**
     * redis 自增默认1
     *
     * @param
     * @param key
     * @param liveTime DAYS 这个计数器的有效存留时间
     * @param formatLength 格式长度
     * @return
     */
    public static String incr(String key, long liveTime,int formatLength) {
        RedisAtomicLong entityIdCounter
                = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
//            自增 然后返回
        Long counter = entityIdCounter.incrementAndGet();
        if ((null == counter || counter.longValue() == 0) && liveTime > 0) {//初始设置过期时间
            entityIdCounter.expire(liveTime, TimeUnit.DAYS);
        }
       return String.format("%0"+formatLength+"d",counter);
    }

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public static Object get(final String key) {
        Object result = null;
        ValueOperations<String, String> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }
    /**
     * @Title: set
     * @Description: set cache.
     * @param key
     * @param value
     * @param expireTime
     */
    public static void set(String key,int value,Date expireTime) {
        RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        counter.set(value);
        counter.expireAt(expireTime);
    }

    /**
     * @Title: set
     * @Description: set cache.
     * @param key
     * @param value
     * @param timeout
     * @param unit
     */
    public static void set(String key,int value,long timeout,TimeUnit unit) {
        RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        counter.set(value);
        counter.expire(timeout, unit);
    }
    /**
     * @Title: generate
     * @Description: Atomically increments by one the current value.
     * @param key
     * @param formatLength 格式长度
     * @return
     */
    public static String generate(String key,int formatLength) {

        RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        //            把数字格式化为i位数
        return String.format("%0"+formatLength+"d",counter.incrementAndGet());
    }

    /**
     * @Title: generate
     * @Description: Atomically increments by one the current value.
     * @param key
     * @param formatLength 格式长度
     * @return
     */
    public static String generate(String key,int formatLength,RedisTemplate redisTemplate) {

        RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        //            把数字格式化为i位数
        return String.format("%0"+formatLength+"d",counter.incrementAndGet());
    }

    /**
     * @Title: generate
     * @Description: Atomically increments by one the current value.
     * @param key
     * @param expireTime  这个 key 将在 expireTime之后 过期
     * @param formatLength 格式长度
     * @return
     */

    public static String generate(String key, Date expireTime,int formatLength) {
        RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        counter.expireAt(expireTime);
        return String.format("%0"+formatLength+"d",counter.incrementAndGet());
    }


    /**
     * @Title: generate
     * @Description: Atomically increments by one the current value.
     * @param key
     * @param expireTime  这个 key 将在 expireTime之后 过期
     * @param formatLength 格式长度
     * @return
     */

    public static String generate(String key, Date expireTime,int formatLength, RedisTemplate redisTemplate) {
        RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        counter.expireAt(expireTime);
        return String.format("%0"+formatLength+"d",counter.incrementAndGet());
    }

    /**
     * @Title: generate
     * @Description: Atomically adds the given value to the current value.
     * @param key
     * @param increment  自增量
     * @param formatLength 格式长度
     * @return
     */
    public static String generate(String key, int increment, int formatLength) {
        RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        return String.format("%0"+formatLength+"d",counter.addAndGet(increment));
    }

    /**
     * @Title: generate
     * @Description: Atomically adds the given value to the current value.
     * @param key
     * @param increment
     * @param expireTime
     * @param formatLength 格式长度
     * @return
     */
    public static String generate(String key, int increment, Date expireTime, int formatLength) {
        RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        counter.expireAt(expireTime);
        return String.format("%0"+formatLength+"d",counter.addAndGet(increment));
    }

    /**
     * 获取下一个值
     */
    public static String nextVal(String key, Date expireAt,int formatLength) {
        RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        long val = redisAtomicLong.incrementAndGet();
        if (val == 1 && expireAt != null) {
            redisAtomicLong.expireAt(expireAt);
        }
        return String.format("%0"+formatLength+"d",val);
    }


    /**
     * 获取下一个值
     * @author Chenpeng.Huang
     * @date 2021/08/09 16:29
     * @param key key
     * @param defaultValue 默认初始值
     * @param expireAt 过期时间
     * @return java.lang.Long
     */
    public static Long nextVal(String key, Long defaultValue, Date expireAt) {
        Object obj = get(key);
        RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, RedisSequenceUtil.redisTemplate.getConnectionFactory());
        long val;
        if (obj == null){
            redisAtomicLong.set(defaultValue);
            val = defaultValue;
        }else {
            val = redisAtomicLong.incrementAndGet();
        }
        if (expireAt != null) {
            redisAtomicLong.expireAt(expireAt);
        }
        return val;
    }
}
